#pragma once
//#include <Ogre.h>
#include <string>
#include <list>
#include "STGEngine.h"

class GameObject {
public:
    GameObject(const std::string &name, const std::string &scriptName):mName(name), mScriptName(scriptName) {}
    virtual ~GameObject();
    void setConfigScript(const std::string &name) { mScriptName = name; }
    
    virtual class GameInst* createInstance(const std::string &name) = 0;
    virtual void removeInstance(GameInst* Inst) {
        mInstances.remove(Inst);
    };
    virtual void loadConfigScript() {};
protected:
    std::string mScriptName;
    std::list<class GameInst*> mInstances;
    std::string mName;
};

class GameInst {
public:
    GameInst(GameObject *pObject, const std::string &name)
        :mGameObject(pObject), mName(name), mNode(NULL), mEntity(NULL) {
            mNode = CSTGEngine::getSingletonPtr()->getSceneManager()->getRootSceneNode()
                ->createChildSceneNode();
    }
    virtual ~GameInst() {
        if (mEntity) {
            mNode->detachObject(mEntity);
            CSTGEngine::getSingletonPtr()->getSceneManager()->destroyMovableObject(mEntity);
            CSTGEngine::getSingletonPtr()->getSceneManager()->destroySceneNode(mNode);
            mGameObject->removeInstance(this);
        }
    }

    virtual void update(float dt){};
    //template<class GameObjectType>
    std::string mName;
    /*virtual*/ void setParent(class GameInst* pInst) {
        if (mNode->getParentSceneNode())
            mNode->getParentSceneNode()->removeChild(mNode);
        if (pInst)
            pInst->mNode->addChild(mNode);
    }
    ///*virtual*/ void addChild(class GameInst* pInst) {
    //    assert(pInst);
    //    if (pInst->mNode->getParentSceneNode()) {
    //        pInst->mNode->getParentSceneNode()->removeChild(mNode);
    //    }
    //    mNode->addChild(pInst);
    //}
protected:
    Ogre::SceneNode *mNode;
    Ogre::MovableObject *mEntity;
    GameObject *mGameObject;
};